package org.datasetcreator.reader;

import java.io.File;
import java.util.Iterator;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.mapping.Table;

public class TableFileCreator {

	private static final Log LOG = LogFactory.getLog(TableFileCreator.class);

	private static final String INITIAL_PART_QUERY = "CALL CSVWRITE('";
	private static final String CENTER_PART_QUERY = "', 'SELECT * FROM ";
	private static final String FINAL_PART_QUERY = "')";
	private String basePath;
	private SessionFactory factory;
	private Configuration conf;

	public TableFileCreator(String basePath, SessionFactory factory,
			Configuration conf) {
		this.basePath = basePath;
		this.factory = factory;
		this.conf = conf;
	}

	@SuppressWarnings("unchecked")
	public void createTableFiles() {
		if (LOG.isInfoEnabled()) {
			LOG.info("Going to create table files.......");
		}
		Session session = getOpenSession();
		Iterator tableMappingIterator = conf.getTableMappings();
		File tableFile = null;
		if (LOG.isInfoEnabled()) {
			LOG.info("Getting list of tables. Output path is : " + basePath);
		}
		while (tableMappingIterator.hasNext()) {
			Table table = (Table) tableMappingIterator.next();
			tableFile = new File(basePath + "/" + table.getName() + ".csv");
			String queryString = INITIAL_PART_QUERY + tableFile
					+ CENTER_PART_QUERY + table.getName() + FINAL_PART_QUERY;
			Query query = session.createSQLQuery(queryString);
			query.executeUpdate();
		}
		if (LOG.isDebugEnabled()) {
			LOG.debug("Flushing the session.......");
		}
		session.flush();
	}

	@SuppressWarnings("unchecked")
	public void insertData(EntityGenerator generator) {
		Session session = getOpenSession();
		for (Class key : generator.getEntitiesMap().keySet()) {
			java.util.List objects = generator.getEntitiesMap().get(key);
			for (Object obj : objects) {
				session.saveOrUpdate(obj);
			}
		}
		session.flush();

	}

	private Session getOpenSession() {
		if (LOG.isDebugEnabled()) {
			LOG.debug("Acquiring hibernate session.......");
		}
		Session session = factory.getCurrentSession();
		if (!session.isOpen()) {
			session = factory.openSession();
		}

		return session;
	}

}
